/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.bizentity.json.object;

import com.fasterxml.jackson.core.JsonParser;
import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.LogicDeleteControlInfo;
import com.inspur.edp.bef.bizentity.beenum.BETriggerTimePointType;
import com.inspur.edp.bef.bizentity.common.BizEntityJsonConst;
import com.inspur.edp.bef.bizentity.common.InternalActionUtil;
import com.inspur.edp.bef.bizentity.common.OperationConvertUtils;
import com.inspur.edp.bef.bizentity.json.element.BizElementDeserializer;
import com.inspur.edp.bef.bizentity.json.operation.BizActionCollectionDeserializer;
import com.inspur.edp.bef.bizentity.json.operation.BizCommonDeterminationDeSerializer;
import com.inspur.edp.bef.bizentity.json.operation.BizCommonValdationDeSerializer;
import com.inspur.edp.bef.bizentity.json.operation.DtmCollectionDeserializer;
import com.inspur.edp.bef.bizentity.json.operation.TccSettingCollectionDeserializer;
import com.inspur.edp.bef.bizentity.json.operation.ValCollectionDeserializer;
import com.inspur.edp.bef.bizentity.operation.BizOperation;
import com.inspur.edp.bef.bizentity.operation.collection.BizActionCollection;
import com.inspur.edp.bef.bizentity.operation.collection.DeterminationCollection;
import com.inspur.edp.bef.bizentity.operation.collection.TccSettingCollection;
import com.inspur.edp.bef.bizentity.operation.collection.ValidationCollection;
import com.inspur.edp.bef.bizentity.operation.internalbeaction.DeleteBEAction;
import com.inspur.edp.bef.bizentity.operation.internalbeaction.ModifyBEAction;
import com.inspur.edp.bef.bizentity.operation.internalbeaction.RetrieveBEAction;
import com.inspur.edp.cef.designtime.api.collection.CommonDtmCollection;
import com.inspur.edp.cef.designtime.api.entity.GspCommonDataType;
import com.inspur.edp.cef.designtime.api.json.SerializerUtils;
import com.inspur.edp.cef.designtime.api.json.operation.CommonDtmDeserializer;
import com.inspur.edp.cef.designtime.api.json.operation.CommonValDeserializer;
import com.inspur.edp.das.commonmodel.entity.GspCommonObject;
import com.inspur.edp.das.commonmodel.entity.object.GspCommonObjectType;
import com.inspur.edp.das.commonmodel.json.element.CmElementDeserializer;
import com.inspur.edp.das.commonmodel.json.object.CmObjectDeserializer;
import java.io.IOException;

public class BizObjectDeserializer extends CmObjectDeserializer {

  @Override
  protected void beforeCMObjectDeserializer(GspCommonObject commonObject) {
    GspBizEntityObject object = (GspBizEntityObject) commonObject;
    object.setDeterminations(new DeterminationCollection());
    object.setValidations(new ValidationCollection());
    object.setTccSettings(new TccSettingCollection());
    LogicDeleteControlInfo info = new LogicDeleteControlInfo();
    info.setEnableLogicDelete(false);
    object.setLogicDeleteControlInfo(info);
  }

  @Override
  protected CmObjectDeserializer createCmObjectDeserializer() {
    return new BizObjectDeserializer();
  }

  public CommonDtmDeserializer getCommonDtmDeserializer() {
    return new BizCommonDeterminationDeSerializer();
  }

  public CommonValDeserializer getCommonValDeserializer() {
    return new BizCommonValdationDeSerializer();
  }

  @Override
  protected boolean ReadExtendObjectProperty(GspCommonObject commonObject, String propName,
      JsonParser jsonParser) {
    boolean result = true;
    GspBizEntityObject object = (GspBizEntityObject) commonObject;
    switch (propName) {
      case BizEntityJsonConst.Determinations:
        DeterminationCollection dtms = readDeterminations(jsonParser, object);
        object.setDeterminations(dtms);
        //如果是新版编辑器保存  不拆分时机(旧元数据 用新编辑器打开保存的时候，会用到)
        if (!getFlag().equals("V2") && dtms != null && !dtms.isEmpty()) {
          object.setDtmBeforeQuery(OperationConvertUtils
              .convertToCommonDtms(dtms, BETriggerTimePointType.BeforeQuery));
          object.setDtmAfterQuery(OperationConvertUtils
              .convertToCommonDtms(dtms, BETriggerTimePointType.AfterQuery));
          object.setDtmBeforeRetrieve(OperationConvertUtils
              .convertToCommonDtms(dtms, BETriggerTimePointType.BeforeRetrieve));
          object.setDtmAfterLoading(OperationConvertUtils
              .convertToCommonDtms(dtms, BETriggerTimePointType.AfterLoading));
          object.setDtmAfterModify(OperationConvertUtils
              .convertToCommonDtms(dtms, BETriggerTimePointType.AfterModify));
          object.setDtmBeforeSave(OperationConvertUtils
              .convertToCommonDtms(dtms, BETriggerTimePointType.BeforeCheck));
          object.setDtmAfterCreate(OperationConvertUtils
              .convertToCommonDtms(dtms, BETriggerTimePointType.RetrieveDefault));
          object.setDtmCancel(OperationConvertUtils
              .convertToCommonDtms(dtms, BETriggerTimePointType.Cancel));
        }
        break;
      case BizEntityJsonConst.Validations:
        ValidationCollection vals = readValidations(jsonParser, object);
        object.setValidations(vals);
        if (vals != null && !vals.isEmpty()) {
          object.setValAfterSave(OperationConvertUtils
              .convertToCommonValidations(vals, BETriggerTimePointType.AfterSave));
          object.setValAfterModify(OperationConvertUtils
              .convertToCommonValidations(vals, BETriggerTimePointType.AfterModify));
          object.setValBeforeSave(OperationConvertUtils
              .convertToCommonValidations(vals, BETriggerTimePointType.BeforeCheck));
        }
        break;
      case BizEntityJsonConst.BizActions:
        readBizActions(jsonParser, object);
        break;
      case BizEntityJsonConst.AuthFieldInfos:
        readAuthFieldInfos(jsonParser, object);
        break;
      case BizEntityJsonConst.ValidationAfterSave:
        object.setValAfterSave(readCommonValidationCollection(jsonParser));
        break;
      case BizEntityJsonConst.LogicDeleteControlInfo:
        object.setLogicDeleteControlInfo(
            SerializerUtils.readPropertyValue_Object(LogicDeleteControlInfo.class, jsonParser));
        try {
          jsonParser.nextToken();
        } catch (IOException e) {
          e.printStackTrace();
        }
        break;
      case BizEntityJsonConst.TccSettings:
        readTccSettings(jsonParser, object);
        break;
      case BizEntityJsonConst.ItemDeletingDtm:
        object.setItemDeletingDtms(readCommonDtmCollection(jsonParser));
        break;
      case BizEntityJsonConst.B4QueryDtm:
        object.setDtmBeforeQuery(readCommonDtmCollection(jsonParser));
        addDetermin(object, object.getDtmBeforeQuery(), BETriggerTimePointType.BeforeQuery);
        break;
      case BizEntityJsonConst.AftQueryDtm:
        object.setDtmAfterQuery(readCommonDtmCollection(jsonParser));
        addDetermin(object, object.getDtmAfterQuery(), BETriggerTimePointType.AfterQuery);
        break;
      case BizEntityJsonConst.DtmCancel:
        object.setDtmCancel(readCommonDtmCollection(jsonParser));
        addDetermin(object, object.getDtmCancel(), BETriggerTimePointType.Cancel);
        break;
      case BizEntityJsonConst.B4RetrieveDtm:
        object.setDtmBeforeRetrieve(readCommonDtmCollection(jsonParser));
        addDetermin(object, object.getDtmBeforeRetrieve(), BETriggerTimePointType.BeforeRetrieve);
        break;
      case BizEntityJsonConst.AftLoadingDtm:
        object.setDtmAfterLoading(readCommonDtmCollection(jsonParser));
        addDetermin(object, object.getDtmAfterLoading(), BETriggerTimePointType.AfterLoading);
        break;
      case BizEntityJsonConst.ItemDeletingVal:
        object.setItemDeletingVals(readCommonValidationCollection(jsonParser));
        break;
      default:
        result = false;
    }
    return result;
  }

  public void addDetermination(GspCommonDataType commonDataType, CommonDtmCollection dtms,
      String triggerType) {
    switch (triggerType) {
      case "beforeSave":
        addDetermin(commonDataType, dtms, BETriggerTimePointType.BeforeCheck);
        break;
      case "afterModify":
        addDetermin(commonDataType, dtms, BETriggerTimePointType.AfterModify);
        break;
      case "afterCreate":
        addDetermin(commonDataType, dtms, BETriggerTimePointType.RetrieveDefault);
        break;
    }
  }

  private void addDetermin(GspCommonDataType commonDataType,
      CommonDtmCollection commonDeterminations, BETriggerTimePointType beTriggerTimePointType) {
//        if(commonDeterminations == null || commonDeterminations.size() == 0)
//            return;
//        GspBizEntityObject bizEntityObject = (GspBizEntityObject) commonDataType;
//        DeterminationCollection dtms = OperationConvertUtils.convertToDtmCollection(commonDeterminations, beTriggerTimePointType);
//        if(bizEntityObject.getDeterminations() == null || bizEntityObject.getDeterminations().size() == 0){
//            bizEntityObject.setDeterminations(dtms);
//            return;
//        }
//        for(BizOperation determination : dtms){
//            Determination dtm = (Determination) determination;
//            BizOperation exist = bizEntityObject.getDeterminations().stream().filter(item -> item.getID().equals(dtm.getID())).findFirst().orElse(null);
//            if(exist == null){
//                bizEntityObject.getDeterminations().add(dtm);
//            }
//        }
  }

  private void readAuthFieldInfos(JsonParser jsonParser, GspBizEntityObject object) {
    SerializerUtils.readStringArray(jsonParser);
  }

  private void readBizActions(JsonParser jsonParser, GspBizEntityObject object) {
    //    BizActionCollectionDeserializer deserializer = new BizActionCollectionDeserializer();
    //    object.setBizActions(deserializer.deserialize(jsonParser, null));
    BizActionCollectionDeserializer deserializer = new BizActionCollectionDeserializer();
    BizActionCollection actionCollection = deserializer.deserialize(jsonParser, null);
    for (BizOperation action : actionCollection) {
      if (!InternalActionUtil.InternalBeActionIDs.contains(action.getID())) {
        object.getBizActions().add(action);
      }
    }
  }

  private ValidationCollection readValidations(JsonParser jsonParser, GspBizEntityObject object) {
    ValCollectionDeserializer deserializer = new ValCollectionDeserializer();
    return deserializer.deserialize(jsonParser, null);
  }

  private DeterminationCollection readDeterminations(JsonParser jsonParser,
      GspBizEntityObject object) {
    DtmCollectionDeserializer deserializer = new DtmCollectionDeserializer();
    return deserializer.deserialize(jsonParser, null);
  }

  private void readTccSettings(JsonParser jsonParser, GspBizEntityObject object) {
    TccSettingCollectionDeserializer deserializer = new TccSettingCollectionDeserializer();
    object.setTccSettings(deserializer.deserialize(jsonParser, null));
  }

  @Override
  protected GspCommonObject CreateCommonObject() {
    return new GspBizEntityObject();
  }

  @Override
  protected CmElementDeserializer CreateElementDeserializer() {
    return new BizElementDeserializer();
  }

  @Override
  protected void afterReadCommonDataType(GspCommonDataType commonDataType) {
    GspBizEntityObject bizObject = (GspBizEntityObject) commonDataType;
    if (bizObject.getObjectType() == GspCommonObjectType.MainObject) {
      BizActionCollection actions;
      actions = null;
      if (bizObject.getBizActions() != null && bizObject.getBizActions().size() > 0) {
        actions = bizObject.getBizActions().clone();
        bizObject.getBizActions().clear();
      }

      bizObject.getBizActions().add(new RetrieveBEAction());
      bizObject.getBizActions().add(new ModifyBEAction());
      bizObject.getBizActions().add(new DeleteBEAction());

      if (actions != null) {
        bizObject.getBizActions().addAll(actions);
      }
    }
  }
}
